﻿using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Citi.Helpers;
using Citi.Scheduler.Domain;

namespace Citi.Scheduler.WindowsUi.MachineAlert
{
    public partial class CurrentStatus : Form
    {
        private const string ServiceGroupBoxName = "Services - Last Update: {0}";
        private const string ControlFileStatusGroupBoxName = "Current Status (.txt) - {0}";
        private bool CloseWindow = false;
        private string machineName = Environment.MachineName;
        //private string machineName = "LACBRA800WL5358";

        public CurrentStatus()
        {
            InitializeComponent();
        }

        private void CurrentStatus_Load(object sender, EventArgs e)
        {
            CreateContextMenuNotifyIcon();

            SetFormPosition();

            Text = string.Format(Text, machineName);

            var machine = new Machine().GetByHostName(machineName);

            if (machine == null)
            {
                Text = "Machine not configured";
                return;
            }

            ServiceStatusTimer = new Timer { Interval = 120000 };
            ServiceStatusTimer.Tick += ServiceStatusTimer_Tick;
            ServiceStatusTimer.Start();
            LoadServicesStatus();

            ControlFileStatusTimer = new Timer { Interval = 30000 };
            ControlFileStatusTimer.Tick += ControlFileStatusTimer_Tick;
            ControlFileStatusTimer.Start();
            ReadControlFile();
        }

        private void CreateContextMenuNotifyIcon()
        {
            var contextMenu = new ContextMenu();

            var menuItemClose = new MenuItem { Text = "Exit" };
            menuItemClose.Click += menuItemClose_Click;

            contextMenu.MenuItems.Add(menuItemClose);
            notifyIcon.ContextMenu = contextMenu;
        }

        void menuItemClose_Click(object sender, EventArgs e)
        {
            CloseWindow = true;
            Close();
            System.Windows.Forms.Application.Exit();
        }

        private void ReadControlFile()
        {
            lblControlFileCurrentStatus.Text = File.ReadAllLines(@"C:\Temp\ExecutionLog.txt").LastOrDefault();
            gpbControlFileStatus.Text = string.Format(ControlFileStatusGroupBoxName, DateTime.Now.ToString("HH:mm:ss"));

            var openForms = System.Windows.Forms.Application.OpenForms.OfType<CurrentExecution>();

            if (lblControlFileCurrentStatus.Text.StartsWith("Executing"))
            {
                var routineExecutionId = int.Parse(lblControlFileCurrentStatus.Text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Last());

                if (!openForms.Any() || routineExecutionId != openForms.First().RoutineExecutionId)
                {
                    if(openForms.Any()) openForms.First().Close();

                    new CurrentExecution(routineExecutionId).Show();
                }
            }
            else if (!lblControlFileCurrentStatus.Text.StartsWith("Executing") && openForms.Any())
                openForms.First().Close();
        }

        void ControlFileStatusTimer_Tick(object sender, EventArgs e)
        {
            ReadControlFile();
        }

        void ServiceStatusTimer_Tick(object sender, EventArgs e)
        {
            LoadServicesStatus();
        }

        private Timer ServiceStatusTimer;
        private Timer ControlFileStatusTimer;

        private void LoadServicesStatus()
        {
            lblExecutionServiceStatus.Text = "Not Applicable";
            lblMonitorServiceStatus.Text = "Not Applicable";
            lblSchedulerServiceStatus.Text = "Not Applicable";
            lblExecutionServiceStatus.ForeColor = Color.Black;
            lblMonitorServiceStatus.ForeColor = Color.Black;
            lblSchedulerServiceStatus.ForeColor = Color.Black;

            var machine = new Machine().GetByHostName(machineName);

            if (machine.ExecutionCenter)
                lblExecutionServiceStatus.Text = WindowsUtil.GetServiceStatus(Machine.ServiceExecutionName, machineName, 10000).GetDescription();

            if (machine.SchedulerCenter)
                lblSchedulerServiceStatus.Text = WindowsUtil.GetServiceStatus(Machine.ServiceSchedulerName, machineName, 10000).GetDescription();

            if (machine.MonitorCenter)
                lblMonitorServiceStatus.Text = WindowsUtil.GetServiceStatus(Machine.ServiceMonitorName, machineName, 10000).GetDescription();

            if (lblExecutionServiceStatus.Text == "Running") lblExecutionServiceStatus.ForeColor = Color.Green;
            if (lblMonitorServiceStatus.Text == "Running") lblMonitorServiceStatus.ForeColor = Color.Green;
            if (lblSchedulerServiceStatus.Text == "Running") lblSchedulerServiceStatus.ForeColor = Color.Green;

            gpbServices.Text = string.Format(ServiceGroupBoxName, DateTime.Now.ToString("dd/MM/yy HH:mm:ss"));
        }

        private void SetFormPosition()
        {
            var x = Screen.PrimaryScreen.WorkingArea.Width - this.Width;
            var y = Screen.PrimaryScreen.WorkingArea.Height - this.Height;

            Location = new Point(x, y);
            TopMost = true;
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Show();
        }

        private void CurrentStatus_Move(object sender, EventArgs e)
        {
            SetFormPosition();
        }

        private void CurrentStatus_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!CloseWindow)
            {
                e.Cancel = true;
                Hide();
            }
        }

        private void CurrentStatus_Activated(object sender, EventArgs e)
        {
            SetFormPosition();
        }
    }
}
